package com.orhonit.ipb.portal.biz;

import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskInfo;
import org.activiti.image.ProcessDiagramGenerator;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.orhonit.ipb.portal.entity.JoApplyJoinParty;
import com.orhonit.ipb.portal.entity.JoStatusTime;
import com.orhonit.ipb.portal.entity.ListenerEntity;
import com.orhonit.ipb.portal.entity.TbPartyOrgBaseInfo;
/**
 * @author Created by yawn on 2018-01-08 13:44
 */
@Service
public class WorkflowServer {

    @Resource
    private RuntimeService runtimeService;
    @Resource
    private ProcessEngine processEngine;
    @Resource
    private IdentityService identityService;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;
    @Resource
    private FormService formService;
    private static final String PROCESS_DEFINE_KEY = "myProcess1";
    @Autowired
    private JoApplyJoinPartyBiz joApplyJoinPartyBiz;
    @Autowired
	private JoJoinInfoBiz joJoinInfoBiz;
    @Autowired
    private JoStatusTimeBiz joStatusTimeBiz;
    @Autowired
    private TbPartyMemberBaseInfoBiz tbPartyMemberBaseInfoBiz;
    @Autowired
	private TbPartyOrgCatalogBiz tbPartyOrgCatalogBiz;
    @Autowired
	private TbPartyOrgBaseInfoBiz tbPartyOrgBaseInfoBiz;
    //开始流程并（员工）
    public Object startVac(String userName,String id) {
    	Map<String, Object> variables = new HashMap<String,Object>();
		/**
		 * 5：	(1)使用流程变量设置字符串（格式：LeaveBill.id的形式），通过设置，让启动的流程（流程实例）关联业务
   				(2)使用正在执行对象表中的一个字段BUSINESS_KEY（Activiti提供的一个字段），让启动的流程（流程实例）关联业务
		 */
		//格式：LeaveBill.id的形式（使用流程变量）
    	String key = "myProcess1";
		String objId = key+"."+id;
		variables.put("objId", objId);
		variables.put("userID", userName);
		//6：使用流程定义的key，启动流程实例，同时设置流程变量，同时向正在执行的执行对象表中的字段BUSINESS_KEY添加业务数据，同时让流程关联业务
		runtimeService.startProcessInstanceByKey(key,objId,variables);

        return true;
    }
    /**使用任务ID，获取当前任务节点中对应的Form key中的连接的值*/
	public String findTaskFormKeyByTaskId(String taskId) {
		TaskFormData formData = formService.getTaskFormData(taskId);
		//获取Form key的值
		String url = formData.getFormKey();
		return url;
	}
    /**指定连线的名称完成任务*/
	@SuppressWarnings("unused")
	public void saveSubmitTask(Map<String, Object> map) {
		//获取任务ID
		String taskId =(String) map.get("taskId");
		//获取连线的名称
		String outcome = (String) map.get("outcome");
		//批注信息
		String message = (String) map.get("message");
		String user=(String) map.get("user");
		//获取请假单ID
		Long id = null;
		
		/**
		 * 1：在完成之前，添加一个批注信息，向act_hi_comment表中添加数据，用于记录对当前申请人的一些审核信息
		 */
		//使用任务ID，查询任务对象，获取流程流程实例ID
		Task task = taskService.createTaskQuery()//
						.taskId(taskId)//使用任务ID查询
						.singleResult();
		//获取流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		/**
		 * 注意：添加批注的时候，由于Activiti底层代码是使用：
		 * 		String userId = Authentication.getAuthenticatedUserId();
			    CommentEntity comment = new CommentEntity();
			    comment.setUserId(userId);
			  所有需要从Session中获取当前登录人，作为该任务的办理人（审核人），对应act_hi_comment表中的User_ID的字段，不过不添加审核人，该字段为null
			 所以要求，添加配置执行使用Authentication.setAuthenticatedUserId();添加当前任务的审核人
		 * */
		Authentication.setAuthenticatedUserId(user);
		taskService.addComment(taskId, processInstanceId, message);
		/**
		 * 2：如果连线的名称是“默认提交”，那么就不需要设置，如果不是，就需要设置流程变量
		 * 在完成任务之前，设置流程变量，按照连线的名称，去完成任务
				 流程变量的名称：outcome
				 流程变量的值：连线的名称
		 */
		Map<String, Object> variables = new HashMap<String,Object>();
		if(outcome!=null && !outcome.equals("默认提交")){
			variables.put("outcome", outcome);
		}
		
		//4：当任务完成之后，需要指定下一个任务的办理人（使用类）-----已经开发完成
		
		/**
		 * 5：在完成任务之后，判断流程是否结束
   			如果流程结束了，更新请假单表的状态从1变成2（审核中-->审核完成）
		 */
		ProcessInstance pi = runtimeService.createProcessInstanceQuery()//
						.processInstanceId(processInstanceId)//使用流程实例ID查询
						.singleResult();
		String businessKey = pi.getBusinessKey();  
        if(StringUtils.isNotBlank(businessKey)){
			//截取字符串，取buniness_key小数点的第2个值
        	businessKey = businessKey.split("\\.")[1];
		}
        JoApplyJoinParty leave=joApplyJoinPartyBiz.getJoApplyJoinPartyByid(businessKey);
        String deptid=tbPartyOrgCatalogBiz.getTbPartyOrgCatalogByDeptId(leave.getParentUserId());
        TbPartyOrgBaseInfo temp1=tbPartyOrgBaseInfoBiz.getTbPartyOrgBaseInfoBypOrganizationCode(deptid);
		String deptid2=tbPartyOrgCatalogBiz.getTbPartyOrgCatalogByDeptId(deptid);
		TbPartyOrgBaseInfo temp2=tbPartyOrgBaseInfoBiz.getTbPartyOrgBaseInfoBypOrganizationCode(deptid2);
		ListenerEntity listenerEntity=new ListenerEntity();
		listenerEntity.setApplyUser(leave.getUserId());//申请人
		listenerEntity.setZhibuUser(leave.getParentUserId());//支部
		listenerEntity.setUpUser(temp1.getPOrganizationCode());//支部上一级党委
		listenerEntity.setUpUpUser(temp2.getPOrganizationCode());//支部上上级 
        variables.put("listenerEntity", listenerEntity);
		//3：使用任务ID，完成当前人的个人任务，同时流程变量
		taskService.complete(taskId, variables);
		//流程结束了
		if(pi!=null){
            if("00".equals(outcome)||"10".equals(outcome)){
            	//拒绝状态
            	Map<String, Object> selectmap=new HashMap<String, Object>();
            	selectmap.put("id", businessKey);
            	selectmap.put("status", leave.getStatus()-1);
            	joApplyJoinPartyBiz.updatestatusByid(selectmap);
            	//删除之前的信息
            	if(leave.getStatus()-1==18){
            		Map<String, Object> talkForUpDept=new HashMap<String, Object>();
            		talkForUpDept.put("joinId", businessKey);
            		talkForUpDept.put("label", "talkForUpDept");
            		joJoinInfoBiz.deleteJoJoinInfoByMap(talkForUpDept);
            	}
            	if(leave.getStatus()-1==26){
            		//删除之前的信息
            		Map<String, Object> consentFullqz=new HashMap<String, Object>();
            		consentFullqz.put("joinId", businessKey);
            		consentFullqz.put("label", "consentFullqz");
            		
            		Map<String, Object> consentFulldy=new HashMap<String, Object>();
            		consentFulldy.put("joinId", businessKey);
            		consentFulldy.put("label", "consentFulldy");
            		
            		Map<String, Object> consentcheck=new HashMap<String, Object>();
            		consentcheck.put("joinId", businessKey);
            		consentcheck.put("label", "consentcheck");
            		
            		Map<String, Object> consentFull=new HashMap<String, Object>();
            		consentFull.put("joinId", businessKey);
            		consentFull.put("label", "consentFull");
            		
            		Map<String, Object> consentFulls=new HashMap<String, Object>();
            		consentFulls.put("joinId", businessKey);
            		consentFulls.put("label", "consentFulls");
            		
            		Map<String, Object> consentFullPub=new HashMap<String, Object>();
            		consentFullPub.put("joinId", businessKey);
            		consentFullPub.put("label", "consentFullPub");
            		
            		Map<String, Object> consentFullRep=new HashMap<String, Object>();
            		consentFullRep.put("joinId", businessKey);
            		consentFullRep.put("label", "consentFullRep");
            		
            		joJoinInfoBiz.deleteJoJoinInfoByMap(consentFullqz);
            		joJoinInfoBiz.deleteJoJoinInfoByMap(consentFulldy);
            		joJoinInfoBiz.deleteJoJoinInfoByMap(consentcheck);
            		joJoinInfoBiz.deleteJoJoinInfoByMap(consentFull);
            		joJoinInfoBiz.deleteJoJoinInfoByMap(consentFulls);
            		joJoinInfoBiz.deleteJoJoinInfoByMap(consentFullPub);
            		joJoinInfoBiz.deleteJoJoinInfoByMap(consentFullRep);
            	}
            }
            else{
            	//JoApplyJoinParty leave=joApplyJoinPartyBiz.getJoApplyJoinPartyByid(businessKey);
            	Map<String, Object> selectmap=new HashMap<String, Object>();
            	selectmap.put("id", businessKey);
            	selectmap.put("status", leave.getStatus()+1);
        		joApplyJoinPartyBiz.updatestatusByid(selectmap);
        		//积极分子
        		if(leave.getStatus()==2){
        			JoStatusTime jo=new JoStatusTime();
        			jo.setApplyId(businessKey);
        			jo.setActivist(new Date());
        			joStatusTimeBiz.updateactivist(jo);
        			Map<String, Object> update=new HashMap<String, Object>();
        			update.put("userId", leave.getUserId());
        			update.put("pmType", "积极分子");
        			tbPartyMemberBaseInfoBiz.updateTbPartyMemberBaseInfopmTypeByUserId(update);
        		}
        		//发展对象
        		else if(leave.getStatus()==7){
        			JoStatusTime jo=new JoStatusTime();
        			jo.setApplyId(businessKey);
        		    jo.setDevelopmentObject(new Date());
        			joStatusTimeBiz.updateactivist(jo);
        			
        		}
        		//预备党员
        		else if(leave.getStatus()==13){
        			JoStatusTime jo=new JoStatusTime();
        			jo.setApplyId(businessKey);
        		    jo.setProbationary(new Date());
        			joStatusTimeBiz.updateactivist(jo);
        			Map<String, Object> update=new HashMap<String, Object>();
        			update.put("userId", leave.getUserId());
        			update.put("pmType", "预备党员");
        			tbPartyMemberBaseInfoBiz.updateTbPartyMemberBaseInfopmTypeByUserId(update);
        		}
            }
		}
		else{
			JoStatusTime jo=new JoStatusTime();
			jo.setApplyId(businessKey);
		    jo.setCorrect(new Date());
			joStatusTimeBiz.updateactivist(jo);
			Map<String, Object> update=new HashMap<String, Object>();
			update.put("userId", leave.getUserId());
			update.put("pmType", "党员");
			tbPartyMemberBaseInfoBiz.updateTbPartyMemberBaseInfopmTypeByUserId(update);
		}
	}
    
	/**2：使用当前用户名查询正在执行的任务表，获取当前任务的集合List<Task>*/
	public List<JoApplyJoinParty> findTaskListByName(String name) {
		List<JoApplyJoinParty> lists=new ArrayList<JoApplyJoinParty>();
		List<Task> list = taskService.createTaskQuery().processDefinitionKey(PROCESS_DEFINE_KEY)//
					.taskAssignee(name)//指定个人任务查询
					.orderByTaskCreateTime().asc()//
					.list();
		 int i=0;  
		for (Task task : list) {  
			System.out.println(task.getProcessDefinitionId());
            String processInstanceId = task.getProcessInstanceId();  
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();  
            String businessKey = processInstance.getBusinessKey();  
            if (businessKey == null) {  
                continue;  
            }
            if(StringUtils.isNotBlank(businessKey)){
    			//截取字符串，取buniness_key小数点的第2个值
            	businessKey = businessKey.split("\\.")[1];
    		}
            JoApplyJoinParty leave=joApplyJoinPartyBiz.innitJoApplyJoinParty(processInstanceId, task.getId(), businessKey);
            leave.setProcessDefinitionId(task.getProcessDefinitionId());
            lists.add(leave);   
            i=i+1;  
        }  
		return lists;
	}
	/**一：使用任务ID，查找请假单ID，从而获取请假单信息*/
	public JoApplyJoinParty findApplyByTaskId(String taskId) {
		//1：使用任务ID，查询任务对象Task
		Task task = taskService.createTaskQuery()//
						.taskId(taskId)//使用任务ID查询
						.singleResult();
		//2：使用任务对象Task获取流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		//3：使用流程实例ID，查询正在执行的执行对象表，返回流程实例对象
		ProcessInstance pi = runtimeService.createProcessInstanceQuery()//
						.processInstanceId(processInstanceId)//使用流程实例ID查询
						.singleResult();
		//4：使用流程实例对象获取BUSINESS_KEY
		String buniness_key = pi.getBusinessKey();
		//5：获取BUSINESS_KEY对应的主键ID，使用主键ID，查询请假单对象（LeaveBill.1）
		String id = "";
		if(StringUtils.isNotBlank(buniness_key)){
			//截取字符串，取buniness_key小数点的第2个值
			id = buniness_key.split("\\.")[1];
		}
		JoApplyJoinParty leave=joApplyJoinPartyBiz.innitJoApplyJoinParty(processInstanceId, task.getId(), id);
		return leave;
	}
   
	/**2：使用当前用户名查询正在执行的任务表，获取当前任务的集合List<Task>*/
	public List<JoApplyJoinParty> findHistoryListByName(String name) {
		List<JoApplyJoinParty> lists=new ArrayList<JoApplyJoinParty>();
		/*List<HistoricProcessInstance> hisProInstance = historyService.createHistoricProcessInstanceQuery()
                .processDefinitionKey(PROCESS_DEFINE_KEY).startedBy(name).finished()
                .orderByProcessInstanceEndTime().desc().list();*/
		List<HistoricProcessInstance> hisProInstance = historyService.createHistoricProcessInstanceQuery()
                .processDefinitionKey(PROCESS_DEFINE_KEY).involvedUser(name)
                .orderByProcessInstanceStartTime().desc().list();
		for (HistoricProcessInstance his : hisProInstance) {
			System.out.println("处理时间"+his.getProcessDefinitionId());  
	        System.out.println("任务名称:"+his.getId());  
	        System.out.println("===========================");  
            //String processInstanceId = his.getSuperProcessInstanceId();  
           // ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();  
            String businessKey = his.getBusinessKey();  
            if (businessKey == null) {  
                continue;  
            }
            if(StringUtils.isNotBlank(businessKey)){
    			//截取字符串，取buniness_key小数点的第2个值
            	businessKey = businessKey.split("\\.")[1];
    		}
            JoApplyJoinParty leave=joApplyJoinPartyBiz.getJoApplyJoinPartyByid(businessKey);
            if(leave!=null){
            	 leave.setProcessDefinitionId(his.getProcessDefinitionId());
                 leave.setProcessInstanceId(his.getId());
                 lists.add(leave);   
            }
            for(int i=0;i<lists.size();i++){
   			 for (int j = lists.size()-1; j > i; j--) {  
   				 if(lists.get(i).getId().equals(lists.get(j).getId())){
   					 lists.remove(j);
   				 }
   			 }
   		}
           
        }  
		
		return lists;
	}
	
	/**获取批注信息，传递的是当前任务ID，获取历史任务ID对应的批注*/
	public List<Comment> findCommentByTaskId(String taskId) {
		List<Comment> list = new ArrayList<Comment>();
		//使用当前的任务ID，查询当前流程对应的历史任务ID
		//使用当前任务ID，获取当前任务对象
		Task task = taskService.createTaskQuery()//
				.taskId(taskId)//使用任务ID查询
				.singleResult();
		//获取流程实例ID
		
		String processInstanceId = task.getProcessInstanceId();
//		//使用流程实例ID，查询历史任务，获取历史任务对应的每个任务ID
//		List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()//历史任务表查询
//						.processInstanceId(processInstanceId)//使用流程实例ID查询
//						.list();
//		//遍历集合，获取每个任务ID
//		if(htiList!=null && htiList.size()>0){
//			for(HistoricTaskInstance hti:htiList){
//				//任务ID
//				String htaskId = hti.getId();
//				//获取批注信息
//				List<Comment> taskList = taskService.getTaskComments(htaskId);//对用历史完成后的任务ID
//				list.addAll(taskList);
//			}
//		}
		list = taskService.getProcessInstanceComments(processInstanceId);
		return list;
	}
	
	/**使用请假单ID，查询历史批注信息*/
	public List<Comment> findCommentByapplyId(String id) {
		//使用请假单ID，查询请假单对象
		String objId = "myProcess1."+id;
		/**1:使用历史的流程实例查询，返回历史的流程实例对象，获取流程实例ID*/
		/**2:使用历史的流程变量查询，返回历史的流程变量的对象，获取流程实例ID*/
		HistoricVariableInstance hvi = historyService.createHistoricVariableInstanceQuery()//对应历史的流程变量表
						.variableValueEquals("objId", objId)//使用流程变量的名称和流程变量的值查询
						.singleResult();
		//流程实例ID
		String processInstanceId = hvi.getProcessInstanceId();
		List<Comment> list = taskService.getProcessInstanceComments(processInstanceId);
		return list;
	}
	/**
	 * 对已完成的任务及连线设置高亮
	 * @param bpmnModel
	 * @param processDefinitionEntity
	 * @param historicActivityInstances
	 * @return
	 */
	public List<String> getHighLightedFlows(BpmnModel bpmnModel,ProcessDefinitionEntity processDefinitionEntity,List<HistoricActivityInstance> historicActivityInstances)
	{
	    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //24小时制
	    List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId

	    for (int i = 0; i < historicActivityInstances.size() - 1; i++)
	    {
	        // 对历史流程节点进行遍历
	        // 得到节点定义的详细信息
	        FlowNode activityImpl = (FlowNode)bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(i).getActivityId());


	        List<FlowNode> sameStartTimeNodes = new ArrayList<FlowNode>();// 用以保存后续开始时间相同的节点
	        FlowNode sameActivityImpl1 = null;

	        HistoricActivityInstance activityImpl_ = historicActivityInstances.get(i);// 第一个节点
	        HistoricActivityInstance activityImp2_ ;

	        for(int k = i + 1 ; k <= historicActivityInstances.size() - 1; k++)
	        {
	            activityImp2_ = historicActivityInstances.get(k);// 后续第1个节点

	            if ( activityImpl_.getActivityType().equals("userTask") && activityImp2_.getActivityType().equals("userTask") &&
	                    df.format(activityImpl_.getStartTime()).equals(df.format(activityImp2_.getStartTime()))   ) //都是usertask，且主节点与后续节点的开始时间相同，说明不是真实的后继节点
	            {

	            }
	            else
	            {
	                sameActivityImpl1 = (FlowNode)bpmnModel.getMainProcess().getFlowElement(historicActivityInstances.get(k).getActivityId());//找到紧跟在后面的一个节点
	                break;
	            }

	        }
	        sameStartTimeNodes.add(sameActivityImpl1); // 将后面第一个节点放在时间相同节点的集合里
	        for (int j = i + 1; j < historicActivityInstances.size() - 1; j++)
	        {
	            HistoricActivityInstance activityImpl1 = historicActivityInstances.get(j);// 后续第一个节点
	            HistoricActivityInstance activityImpl2 = historicActivityInstances.get(j + 1);// 后续第二个节点

	            if (df.format(activityImpl1.getStartTime()).equals(df.format(activityImpl2.getStartTime()))  )
	            {// 如果第一个节点和第二个节点开始时间相同保存
	                FlowNode sameActivityImpl2 = (FlowNode)bpmnModel.getMainProcess().getFlowElement(activityImpl2.getActivityId());
	                sameStartTimeNodes.add(sameActivityImpl2);
	            }
	            else
	            {// 有不相同跳出循环
	                break;
	            }
	        }
	        List<SequenceFlow> pvmTransitions = activityImpl.getOutgoingFlows() ; // 取出节点的所有出去的线

	        for (SequenceFlow pvmTransition : pvmTransitions)
	        {// 对所有的线进行遍历
	            FlowNode pvmActivityImpl = (FlowNode)bpmnModel.getMainProcess().getFlowElement( pvmTransition.getTargetRef());// 如果取出的线的目标节点存在时间相同的节点里，保存该线的id，进行高亮显示
	            if (sameStartTimeNodes.contains(pvmActivityImpl)) {
	                highFlows.add(pvmTransition.getId());
	            }
	        }

	    }
	    return highFlows;

	}
	/**
	 * 获取流程图像，已执行节点和流程线高亮显示
	 */
	public void getActivitiProccessImage(String pProcessInstanceId, HttpServletResponse response)
	{
	    //logger.info("[开始]-获取流程图图像");
	    try {
	        //  获取历史流程实例
	        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
	                .processInstanceId(pProcessInstanceId).singleResult();

	        if (historicProcessInstance == null) {
	            //throw new BusinessException("获取流程实例ID[" + pProcessInstanceId + "]对应的历史流程实例失败！");
	        }
	        else
	        {
	            // 获取流程定义
	            ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
	                    .getDeployedProcessDefinition(historicProcessInstance.getProcessDefinitionId());

	            // 获取流程历史中已执行节点，并按照节点在流程中执行先后顺序排序
	            List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
	                    .processInstanceId(pProcessInstanceId).orderByHistoricActivityInstanceId().asc().list();

	            // 已执行的节点ID集合
	            List<String> executedActivityIdList = new ArrayList<String>();
	            int index = 1;
	            //logger.info("获取已经执行的节点ID");
	            for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
	                executedActivityIdList.add(activityInstance.getActivityId());

	                //logger.info("第[" + index + "]个已执行节点=" + activityInstance.getActivityId() + " : " +activityInstance.getActivityName());
	                index++;
	            }

	            BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());

	            // 已执行的线集合
	            List<String> flowIds = new ArrayList<String>();
	            // 获取流程走过的线 (getHighLightedFlows是下面的方法)
	            flowIds = getHighLightedFlows(bpmnModel,processDefinition, historicActivityInstanceList);



	            // 获取流程图图像字符流
	            ProcessDiagramGenerator pec = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();
	            //配置字体
	            InputStream imageStream = pec.generateDiagram(bpmnModel, "png", executedActivityIdList, flowIds,"宋体","微软雅黑","黑体",null,2.0);

	            response.setContentType("image/png");
	            OutputStream os = response.getOutputStream();
	            int bytesRead = 0;
	            byte[] buffer = new byte[8192];
	            while ((bytesRead = imageStream.read(buffer, 0, 8192)) != -1) {
	                os.write(buffer, 0, bytesRead);
	            }
	            os.close();
	            imageStream.close();
	        }
	        //logger.info("[完成]-获取流程图图像");
	    } catch (Exception e) {
	        System.out.println(e.getMessage());
	        //logger.error("【异常】-获取流程图失败！" + e.getMessage());
	        //throw new BusinessException("获取流程图失败！" + e.getMessage());
	    }
	}
	
	
}
